package org.dfl.plugin.views.palette.model;

import java.util.ArrayList;
import java.util.Collection;

import org.dfl.plugin.DflPlugin;
import org.dfl.plugin.views.palette.DeltaEvent;
import org.dfl.plugin.views.palette.IDeltaListener;
import org.dfl.plugin.views.palette.model.PaletteEntry;
import org.eclipse.gef.Tool;
import org.eclipse.jface.resource.ImageDescriptor;

/**
 * basic abstract palette entry - element shown in PaletteView
 * @author Piotr Wlodarczyk
 *
 */
public abstract class AbstractPaletteEntry implements PaletteEntry {
	private Collection<IDeltaListener> changeListeners = new ArrayList<IDeltaListener>();
	PaletteEntry parent;
	Collection<PaletteEntry> children = new ArrayList<PaletteEntry>();
	
	public abstract String getLabel();
	public abstract Tool getTool();
	public abstract Object getTransferTemplate();
	public abstract ImageDescriptor getImage();
	
	protected ImageDescriptor createImage(String imageSrc) {
		return DflPlugin.getImageDescriptor(imageSrc);
	}	
	
	public PaletteEntry getParent() {
		return parent;
	}
	
	public void setParent(PaletteEntry parent){
		this.parent = parent;
	}

	public Collection<PaletteEntry> getChildren() {
		return children;
	}
	
	public void addChild(PaletteEntry child){
		children.add(child);
		child.setParent(this);
		for(IDeltaListener l : changeListeners){
			child.addChangeListener(l);
		}
		fireAdd(child);
	}
	
	public void removeChild(PaletteEntry child){
		children.remove(child);
		child.setParent(null);
		for(IDeltaListener l : changeListeners){
			child.removeChangeListener(l);
		}
		fireRemove(child);
	}

	public void removeChangeListener(IDeltaListener l) {
		changeListeners.remove(l);
		for(PaletteEntry child : getChildren()){
			child.removeChangeListener(l);
		}
	}
	
	public void addChangeListener(IDeltaListener l) {
		changeListeners.add(l);		
		for(PaletteEntry child : getChildren()){
			child.addChangeListener(l);
		}
	}
	
	protected void fireAdd(Object added) {
		for(IDeltaListener l : changeListeners){
			l.add(new DeltaEvent(added));
		}
	}

	protected void fireRemove(Object removed) {
		for(IDeltaListener l : changeListeners){
			l.remove(new DeltaEvent(removed));
		}
	}
}
